這次的實作會使用到EditText輸入要搜尋的資料,然後按下按鍵後會叫出Dialog將相關的資料顯示出來,關於這部分的模糊搜尋會用到陣列跟EditText結合,先將假資料加進陣列,然後使用EditText的addTextChangedListener
將相關的資料重新填入到陣列中,最後在讓Dialog裡面的RecyclerView顯示更新過後的陣列的資料,以此來完成模糊搜尋的功能。
首先附上這次的GitHub
這次的實作主要是使用EditText輸入關鍵字,按下搜尋後就去比對輸入的資料,先將原本的陣列清空,再將過濾過的資料都加入到清空的陣列,最後再把更新過資料的陣列丟給Dialog裡面的RecyclerView,用這種方式就可以做出模擬搜尋的效果。
對話框的部分
RecyclerView的Item
這次的實作還做了點擊RecyclerView的選項後,就將資料填到EditText,這部分我是在MainActivity中建立了一個方法,然後在RecyclerView的Adapter中的點擊事件監聽器呼叫了這個方法,在點擊當下就把點擊到的選項傳回到MainActivity的方法,透過點擊後才呼叫方法的方式,將資料填入到EditText。
private ArrayList<String> fuzzyMatching;
先建立一個ArrayList用來存取假資料
fuzzyMatching = new ArrayList<>();
Collections.addAll(fuzzyMatching,getResources().getStringArray(R.array.fruits_name));
將ArrayList初始化後,我使用到Collections.addAll
這個方法,這個可以幫忙將一個陣列的元素加入到另外一個陣列,使用方法是先將要放入資料的陣列填入,接著將資料來源填入就可以囉~
dialog = new Dialog(this);
dialog.setContentView(R.layout.dialog);
recyclerView = dialog.findViewById(R.id.recyclerView);
再來這個部分比較特別的是,RecyclerView因為是放在Dialog裡面,所以要在Dialog初始化並指定完頁面後,才可以綁定物件id
setEditText();
search.setOnClickListener(view -> setDialog(fuzzyMatching));
再來這個部分我將一些較複雜的部份外包出去,搜尋按鈕的部分在建立Dialog的同時將資料傳入
private void setDialog(ArrayList<String> filterData) {
dialogListAdapter = new DialogListAdapter(filterData,this);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter(dialogListAdapter);
dialog.show();
}
因為我將RecyclerView放在Dialog裡面,所以設定RecyclerView的相關設定也都是寫在這裡,這裡我傳入Adapter中的除了資料以外,還傳入了MainActivity,這部分就留到Adapter在詳細說明。
private void setEditText() {
enter_name.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
fuzzyMatching.clear();
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
@Override
public void afterTextChanged(Editable editable) {
String filterText = editable.toString().toLower
fuzzyMatching.clear();
for (String data : getResources().getStringArray(R.array.fruits_name)){
if (data.toLowerCase().contains(filterText)){
fuzzyMatching.add(data);
}
}
}
});
}
這次實作的模糊搜尋使用到EditText的addTextChangedListener
,主要會使用到afterTextChanged
輸入完後會EditText做的事
String filterText = editable.toString().toLower
fuzzyMatching.clear();
這個部分我將輸入的資料用一個String存取,並且讓它全部都變成小寫
接著把原本的資料都清除
for (String data : getResources().getStringArray(R.array.fruits_name)){
if (data.toLowerCase().contains(filterText)){
fuzzyMatching.add(data);
}
}
最後將塞選過的資料填入陣列,用一個String去走訪原本的資料,接著一樣把原本的資料用成小寫,在去對比輸入的資料有沒有包含在原本的資料內,有就將他加進陣列中。
public void receiveData(String data){
enter_name.setText(data);
dialog.dismiss();
}
我先建立了一個public的方法,預計讓Adapter調用
private ArrayList<String> mArrayList;
private MainActivity mainActivity;//為了要調用MainActivity的方法
public DialogListAdapter(ArrayList<String> arrayList,MainActivity activity){
this.mArrayList = arrayList;
this.mainActivity = activity;
//接收資料以及獲取Activity
}
這次跟之前教學一樣,在建構元的部分我設定要傳資料進來,並且還設定要傳送MainActivity的Activity,這樣我就可以使用MainActivity的方法
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView fruits_name;
public ViewHolder(@NonNull View itemView) {
super(itemView);
fruits_name = itemView.findViewById(R.id.fruits_name);
}
}
@NonNull
@Override
public DialogListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycleritem,parent,false);
return new ViewHolder(view);
}
接著綁定id跟item的部分還是一樣
@Override
public void onBindViewHolder(@NonNull DialogListAdapter.ViewHolder holder, int position) {
holder.fruits_name.setText(mArrayList.get(position));
holder.itemView.setOnClickListener(view -> {
mainActivity.receiveData(mArrayList.get(position));
Log.d("test", "按下RecyclerItem");
});
}
再來設定要執行的動作這邊,除了最基本的設定每一個選項的TextView以外,還有設定選項的點擊事件,當點擊後就呼叫MainActivity的reciveData並把點擊到的資料傳進去
public void receiveData(String data){
enter_name.setText(data);
dialog.dismiss();
}
接著這裡就會被呼叫,然後就會執行裡面的動作,將資料填入EditText再將Dialog關閉。